package sjtu.ChatClient;

import org.achartengine.ChartFactory;
import org.achartengine.GraphicalView;
import org.achartengine.chart.BarChart.Type;
import org.achartengine.chart.PointStyle;
import org.achartengine.model.XYMultipleSeriesDataset;
import org.achartengine.model.XYSeries;
import org.achartengine.renderer.XYMultipleSeriesRenderer;
import org.achartengine.renderer.XYSeriesRenderer;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.LinearLayout;
import android.widget.Toast;

import com.neurosky.thinkgear.*;

public class VisualizerActivity extends Activity {
	private BluetoothAdapter bluetoothAdapter = null;
	private TGDevice tgDevice = null;
	
	// bar chart view variables
	private XYSeries attentionSeries;
	private XYSeries meditationSeries;
	private XYSeries signalSeries;
	private XYSeriesRenderer attentionRenderer;
	private XYSeriesRenderer meditationRenderer;
	private XYSeriesRenderer signalRenderer;
	private XYMultipleSeriesDataset barDataset;
	private XYMultipleSeriesRenderer barMainRenderer;
	private GraphicalView barView = null;
	
	// line chart view variables
	private XYSeries lineSeries;
	private XYSeriesRenderer lineSeriesRenderer;
	private XYMultipleSeriesDataset lineDataset;
	private XYMultipleSeriesRenderer lineMainRenderer;
	private GraphicalView lineView = null;
	
	private WakeLock wakeLock;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_visualizer);
		
		this.bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
		if(this.bluetoothAdapter == null){
			Toast.makeText(getBaseContext(), "Bluetooth not available!", Toast.LENGTH_LONG).show();
			finish();
			return;
		} else {
			this.tgDevice = new TGDevice(this.bluetoothAdapter, handler);
		}
		
		// initial bar view variables
		attentionSeries = new XYSeries("Attention");
		meditationSeries = new XYSeries("Meditation");
		signalSeries = new XYSeries("Signal");
		
		barDataset = new XYMultipleSeriesDataset();
		barDataset.addSeries(attentionSeries);
		barDataset.addSeries(meditationSeries);
		barDataset.addSeries(signalSeries);
		
		attentionRenderer = new XYSeriesRenderer();
		attentionRenderer.setColor(Color.BLUE);
		attentionRenderer.setFillPoints(true);
		attentionRenderer.setLineWidth(10);
		attentionRenderer.setDisplayChartValues(true);
		
		meditationRenderer = new XYSeriesRenderer();
		meditationRenderer.setColor(Color.GREEN);
		meditationRenderer.setFillPoints(true);
		meditationRenderer.setLineWidth(10);
		meditationRenderer.setDisplayChartValues(true);
		
		signalRenderer = new XYSeriesRenderer();
		signalRenderer.setColor(Color.RED);
		signalRenderer.setFillPoints(true);
		signalRenderer.setLineWidth(10);
		signalRenderer.setDisplayChartValues(true);
		
		barMainRenderer = new XYMultipleSeriesRenderer();
		barMainRenderer.setApplyBackgroundColor(true);
		barMainRenderer.setBackgroundColor(Color.argb(100, 50, 50, 50));
		barMainRenderer.setXLabels(0);
		barMainRenderer.setChartTitle("MindSet");
		barMainRenderer.setXTitle("");
		barMainRenderer.setYTitle("Value");
		barMainRenderer.setZoomButtonsVisible(true);
		
		barMainRenderer.addSeriesRenderer(attentionRenderer);
		barMainRenderer.addSeriesRenderer(meditationRenderer);
		barMainRenderer.addSeriesRenderer(signalRenderer);
		
		// initial line view variables
		lineDataset = new XYMultipleSeriesDataset();
		lineMainRenderer = new XYMultipleSeriesRenderer();
		
		lineMainRenderer.setApplyBackgroundColor(true);
		lineMainRenderer.setBackgroundColor(Color.argb(100, 50, 50, 50));
		lineMainRenderer.setChartTitle("MindSet");
		lineMainRenderer.setXTitle("");
		lineMainRenderer.setYTitle("Value");
		//lineMainRenderer.setAxisTitleTextSize(16);
		//lineMainRenderer.setChartTitleTextSize(20);
	    //lineMainRenderer.setLabelsTextSize(15);
	    //lineMainRenderer.setLegendTextSize(15);
	    //lineMainRenderer.setMargins(new int[] { 20, 30, 15, 0 });
		lineMainRenderer.setZoomButtonsVisible(true);
	    lineMainRenderer.setPointSize(3);
	    
	    lineSeries = new XYSeries("Raw Data");
	    lineDataset.addSeries(lineSeries);
	    lineSeriesRenderer = new XYSeriesRenderer();
	    lineMainRenderer.addSeriesRenderer(lineSeriesRenderer);
	    lineSeriesRenderer.setPointStyle(PointStyle.CIRCLE);
        lineSeriesRenderer.setFillPoints(true);
        lineSeriesRenderer.setDisplayChartValues(true);
	    lineSeriesRenderer.setDisplayChartValuesDistance(10);
	        
		wakeLock = ((PowerManager)getSystemService(POWER_SERVICE)).newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, "VideoSenderMainActivity");
	}

	protected void onPause(){
		super.onPause();
		
		wakeLock.release();
	}
	
	protected void onResume(){
		super.onResume();
		
		if(barView == null){
			LinearLayout layout = (LinearLayout) this.findViewById(R.id.barChart);
			barView = ChartFactory.getBarChartView(this, barDataset, barMainRenderer, Type.DEFAULT);
		    layout.addView(barView, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
		} else {
			barView.repaint();
		}
		
		if(lineView == null){
			LinearLayout layout = (LinearLayout) findViewById(R.id.lineChart);
		    lineView = ChartFactory.getLineChartView(this, lineDataset, lineMainRenderer);
		    // enable the chart click events
		    lineMainRenderer.setClickEnabled(true);
		    lineMainRenderer.setSelectableBuffer(10);
		    layout.addView(lineView, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
		    
		    int i = 0;
		    for(i = 0;i < 20;i++){
		    	lineSeries.add(i, 0);
		    }
		} else {
			lineView.repaint();
		}
		wakeLock.acquire();
	}
	
	public void onDestroy(){
		super.onDestroy();
		this.tgDevice.close();
	}
	
	private final Handler handler = new Handler(){
		public void handleMessage(Message msg){
			switch(msg.what){
			case TGDevice.MSG_STATE_CHANGE:
				switch(msg.arg1){
				case TGDevice.STATE_IDLE:
					break;
				case TGDevice.STATE_CONNECTING:
					break;
				case TGDevice.STATE_CONNECTED:
					Toast.makeText(getBaseContext(), "Connected", Toast.LENGTH_LONG).show();
					tgDevice.start();//start data flow
					break;
				case TGDevice.STATE_NOT_FOUND:
					Toast.makeText(getBaseContext(), "Not found", Toast.LENGTH_LONG).show();
					break;
				case TGDevice.STATE_NOT_PAIRED:
					Toast.makeText(getBaseContext(), "Not paired", Toast.LENGTH_LONG).show();
					break;
				case TGDevice.STATE_DISCONNECTED:
					Toast.makeText(getBaseContext(), "Disconnected", Toast.LENGTH_LONG).show();
					break;
				default:
					break;
				}
				
				break;
			case TGDevice.MSG_POOR_SIGNAL:
				signalSeries.clear();
				signalSeries.add(1, 100 - msg.arg1 / 2);
				barView.repaint();
				break;
			case TGDevice.MSG_ATTENTION:
				attentionSeries.clear();
				attentionSeries.add(5, msg.arg1);
				barView.repaint();
				break;
			case TGDevice.MSG_MEDITATION:
				meditationSeries.clear();
				meditationSeries.add(9, msg.arg1);
				barView.repaint();
				break;
			case TGDevice.MSG_RAW_DATA:
				int count = lineSeries.getItemCount();
				double [] newValues = new double [count];
				int i = 0;
				for(i = 0;i < count - 1;i++){
					newValues[i] = lineSeries.getY(i + 1);
				}
				newValues[count - 1] = msg.arg1;
				lineSeries.clear();
				for(i = 0;i < newValues.length;i++){
					lineSeries.add(i, newValues[i]);
				}
				lineView.repaint();
				break;
			case TGDevice.MSG_EEG_POWER:
				break;
			case TGDevice.MSG_BLINK:
				break;
			case TGDevice.MSG_LOW_BATTERY:
				Toast.makeText(getBaseContext(), "Low Battery!", Toast.LENGTH_LONG).show();
				break;
			default:
				break;
			}
		}
	};
	
	public void connectToMindSet(View view){
		if(this.tgDevice.getState() != TGDevice.STATE_CONNECTING && this.tgDevice.getState() != TGDevice.STATE_CONNECTED){
			this.tgDevice.connect(true);
		}
	}
	
	public boolean onCreateOptionsMenu(Menu menu){
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.connect_menu, menu);
		return true;
	}
	
	public boolean onOptionsItemSelected(MenuItem item){
		switch(item.getItemId()){
		case R.id.connect:
			if(this.tgDevice.getState() != TGDevice.STATE_CONNECTING && this.tgDevice.getState() != TGDevice.STATE_CONNECTED){
				this.tgDevice.connect(true);
			}
			return true;
		default:
			return super.onOptionsItemSelected(item);
		}
	}
}
